package com.dc.java8._1_lambda;

import org.junit.Test;

import java.util.Comparator;
import java.util.function.*;

/**
 * 一、方法引用：若 Lambda 体中的功能，已经有方法提供了实现，可以使用方法引用
 * 			  （可以将方法引用理解为 Lambda 表达式的另外一种表现形式）
 * 
 * 1. 对象的引用 :: 实例方法名
 * 2. 类名 :: 静态方法名
 * 3. 类名 :: 实例方法名
 * 注意：
 * 	 ①方法引用所引用的方法的参数列表与返回值类型，需要与函数式接口中抽象方法的参数列表和返回值类型保持一致！
 * 	 ②若Lambda 的参数列表的第一个参数，是实例方法的调用者，第二个参数(或无参)是实例方法的参数时，格式： ClassName::MethodName
 * 
 * 二、构造器引用 :构造器的参数列表，需要与函数式接口中参数列表保持一致！
 * 1. 类名 :: new
 * 
 * 三、数组引用
 * 	类型[] :: new;
 */
public class LambdaTest6 {
	
	@Test
	public void test1() {
		Consumer<String> con = System.out::println;
		con.accept("hello world");
	}
	
	/**
	 *   对象的引用:: 实例方法名
	 */
	@Test
	public void test2() {
		Person person = new Person("张", "三", "上学", "男", 18, 1888.8);
		Supplier<String> str = person::getLastName;
		System.out.println(str.get());

		Supplier<String> str1 = person::getLastName;
		System.out.println("----------------------------");
		System.out.println(str1.get());
	}
	
	/**
	 *   类名::静态方法名
	 */
	@Test
	public void test3() {
		BiFunction<Integer, Integer, Integer> fun = Math::max;
		System.out.println(fun.apply(3, 6));

		Comparator<Integer> comp = Integer::compare;
		System.out.println(comp.compare(1, 2));

	}

	/**
	 *  类名::实例方法名
	 */
	@Test
	public void test4() {
		BiPredicate<String, String> bp = String::equals;
		System.out.println(bp.test("abc", "def"));
		System.out.println("-----------------------------------------");
		
		BiPredicate<String, String> bp1 = String::equals;
		System.out.println(bp1.test("abc", "def"));
		System.out.println("-----------------------------------------");
		
		Function<Person, String> fun = Person::getFirstName;
		System.out.println(fun.apply(new Person("张", "三", "上学", "男", 18, 1888.8)));
		System.out.println("-----------------------------------------");
		
		Function<Person, String> fun1 = Person::getFirstName;
		System.out.println(fun1.apply(new Person("张", "三", "上学", "男", 18, 1888.8)));
	}
	
	/**
	 *  构造器引用
	 */
	@Test
	public void test5() {
		// 调用 对应 Person() 构造器
		Supplier<Person> sp = Person::new;
		System.out.println(sp.get());
		System.out.println("-----------------------------------------");

		// 调用 对应 Person(String lastName) 构造器
		Function<String, Person> fun = Person::new;
		Person zhangsan = fun.apply("zhangsan");

		System.out.println("-----------------------------------------");
		// 调用 对应 Person( Integer age,String lastName) 构造器
		BiFunction<Integer, String, Person> fun2 = Person::new;
		Person lisi = fun2.apply(1, "lisi");

	}
	
	
	/**
	 *   数组引用
	 */
	@Test
	public void test6() {
		Function<Integer, String[]> fun = String[]::new;
		String[] strs = fun.apply(10);
		System.out.println(strs.length);
		System.out.println("-----------------------------------------");
		Function<Integer,Person[]> fun1 = Person[]::new;
		Person[] persons = fun1.apply(5);
		System.out.println(persons.length);
	}
}
